package com.sls.game.supply.deal;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import com.google.gson.Gson;
import com.sls.core.common.CommonUtil;
import com.sls.core.http.HttpClient;
import com.sls.core.socket.Head;
import com.sls.core.socket.ServerDisponseException;
import com.sls.core.util.PropertiesUtil;
import com.sls.core.util.UtilMD5Encryption;
import com.sls.game.common.DeductionRefund;
import com.sls.game.constant.ExceptionCodeDes;
import com.sls.game.dao.DownstreamUserDAO;
import com.sls.game.dao.GoodsOrderDAO;
import com.sls.game.dao.GoodsSupplyManageDAO;
import com.sls.game.dao.wogreat.WogreatAccountDAO;
import com.sls.game.dao.wogreat.WogreatAsDAO;
import com.sls.game.dao.wogreat.WogreatRechargeDAO;
import com.sls.game.parser.ParseWogreatRespInfo;
import com.sls.game.pojo.DeductionRefundInfo;
import com.sls.game.pojo.GoodsOrderInfo;
import com.sls.game.pojo.SLSHttpInterfaceInfo;
import com.sls.game.pojo.wogreat.WogreatAccountType;
import com.sls.game.pojo.wogreat.WogreatAreaServer;
import com.sls.game.pojo.wogreat.WogreatRechargeType;
import com.sls.game.pojo.wogreat.WogreatRespInfo;

public class WogreatTradeDeal {

	public static Logger log = Logger.getLogger(WogreatTradeDeal.class);
	private static String filename = "wogreat.properties";

	public static String dealTradeResultOfWogreat(SLSHttpInterfaceInfo info,
			String originalGoodsId, String orderId, String orderTime,
			String paymentOrderNo, Head head, GoodsOrderDAO goodsOrderDAO,
			GoodsSupplyManageDAO goodsSupplyManageDAO,
			DownstreamUserDAO downstreamUserDAO, WogreatAccountDAO accDAO,
			WogreatRechargeDAO rechargeDAO, WogreatAsDAO asDAO,
			String mechantIP, String supplyName, String goodsCostPrice,
			String suppliersId) {
		WogreatRespInfo resInfo = trade(info, originalGoodsId, orderId,
				paymentOrderNo, head, goodsOrderDAO, goodsSupplyManageDAO,
				downstreamUserDAO, accDAO, rechargeDAO, asDAO, mechantIP,
				supplyName, goodsCostPrice, suppliersId);
		// 返回给上层对象
		SLSHttpInterfaceInfo sLSHttpInterfaceInfo = new SLSHttpInterfaceInfo();
		if (resInfo != null) {
			String result = resInfo.getState();
			if ("102".equals(result)) { // 处理中
				sLSHttpInterfaceInfo.setResMsg("SUCCESS");
				sLSHttpInterfaceInfo.setFailedCode("209");
				sLSHttpInterfaceInfo.setFailedReason("处理中");
				sLSHttpInterfaceInfo.setPtOrderNo(info.getPtOrderNo());
				sLSHttpInterfaceInfo.setStatus("ORDER_UNDERWAY");
				sLSHttpInterfaceInfo.setSupOrderNo(orderId);
			} else if ("101".equals(result)) {
				sLSHttpInterfaceInfo.setResMsg("SUCCESS");
				sLSHttpInterfaceInfo.setPtOrderNo(info.getPtOrderNo());
				sLSHttpInterfaceInfo.setStatus("ORDER_SUCCESS");
				sLSHttpInterfaceInfo.setSupOrderNo(orderId);
			} else if ("103".equals(result) || "901".equals(result)
					|| "601".equals(result)) {
				sLSHttpInterfaceInfo.setResMsg("SUCCESS");
				sLSHttpInterfaceInfo.setFailedCode("210");
				sLSHttpInterfaceInfo.setFailedReason("订单存疑");
				sLSHttpInterfaceInfo.setPtOrderNo(info.getPtOrderNo());
				sLSHttpInterfaceInfo.setStatus("ORDER_DUBIOUS");
				sLSHttpInterfaceInfo.setSupOrderNo(orderId);
			} else { // 失败
				sLSHttpInterfaceInfo.setResMsg("FAILED");
				sLSHttpInterfaceInfo.setFailedCode("208");
				sLSHttpInterfaceInfo.setFailedReason("充值失败");
				sLSHttpInterfaceInfo.setPtOrderNo(info.getPtOrderNo());
				sLSHttpInterfaceInfo.setStatus("ORDER_FAILED");
				sLSHttpInterfaceInfo.setSupOrderNo(orderId);

				GoodsOrderInfo goodsOrderInfo = new GoodsOrderInfo();
				DeductionRefundInfo dedInfo = null;
				String paymentStatus = "";
				// 退款
				dedInfo = DeductionRefund.invokeDeductRefund(info, orderId,
						"1", orderTime, paymentOrderNo, head, goodsOrderDAO);
				if (dedInfo != null) {
					paymentStatus = dedInfo.getPaymentStatus();
				}
				if ("1".equals(paymentStatus)) { // 成功
					goodsOrderInfo.setIsPay("3"); // 退款成功
					// 退款成功，通知下游用户
					DeductionRefund.noticeUserRefundMsg(orderId, dedInfo,
							goodsOrderDAO, downstreamUserDAO, null);

				} else if ("2".equals(paymentStatus)) {
					goodsOrderInfo.setIsPay("2"); // 退款失败
				}
				try {
					// 更新订单
					updateGoodsOrder(orderId, head, goodsOrderInfo,
							goodsOrderDAO);
				} catch (Exception e) {
					log.error("请求ID：" + head.getRequestId() + "根据退款状态更新订单异常！",
							e);
				}
			}
		} else {
			sLSHttpInterfaceInfo.setResMsg("SUCCESS");
			sLSHttpInterfaceInfo.setFailedCode("210");
			sLSHttpInterfaceInfo.setFailedReason("订单存疑");
			sLSHttpInterfaceInfo.setPtOrderNo(info.getPtOrderNo());
			sLSHttpInterfaceInfo.setStatus("ORDER_DUBIOUS");
			sLSHttpInterfaceInfo.setSupOrderNo(orderId);
		}
		sLSHttpInterfaceInfo.setGameAccount(info.getGameAccount());
		sLSHttpInterfaceInfo.setUnitPrice(info.getUnitPrice());
		sLSHttpInterfaceInfo.setBuyNum(info.getBuyNum());

		String totalPrice = info.getTotalPrice();
		sLSHttpInterfaceInfo.setTotalPrice(totalPrice);
		Gson gson = CommonUtil.gson();
		String resultBody = gson.toJson(sLSHttpInterfaceInfo);

		return resultBody;
	}

	private static WogreatRespInfo trade(SLSHttpInterfaceInfo info,
			String originalGoodsId, String orderId, String paymentOrderNo,
			Head head, GoodsOrderDAO goodsOrderDAO,
			GoodsSupplyManageDAO goodsSupplyManageDAO,
			DownstreamUserDAO downstreamUserDAO, WogreatAccountDAO accDAO,
			WogreatRechargeDAO rechargeDAO, WogreatAsDAO asDAO,
			String mechantIP, String supplyName, String goodsCostPrice,
			String suppliersId) {
		String address = PropertiesUtil.getValue(
				"wogreat.interface.recharge.address", filename);
		WogreatRespInfo resInfo = null;
		Map<String, String> map = assembleParameterOfTrade(info,
				originalGoodsId, orderId, accDAO, rechargeDAO, asDAO, mechantIP);
		// 发送http请求
		resInfo = sendHttpRequestOfDirectTrade(address, map, head);
		// 上游订单结果
		String orderResult = "";
		String msg = "";
		String wogreatOrderId = "";
		String status = "2";
		if (resInfo != null) {
			// 订单结果
			orderResult = resInfo.getState();
			msg = resInfo.getStateInfo();
			wogreatOrderId = resInfo.getWogreatOrderId();
			if ("101".equals(orderResult)) { // 成功
				status = "1";
			} else if ("102".equals(orderResult)) { // 订单状态处理中
				status = "2";
			} else if ("103".equals(orderResult) || "901".equals(orderResult)
					|| "601".equals(orderResult)) {
				status = "3"; // 存疑
			} else {
				status = "0"; // 失败
			}
		} else {
			status = "3"; // 存疑
		}

		// 工号
		String merchantId = PropertiesUtil.getValue("wogreat.merchant.id",
				filename);
		GoodsOrderInfo goodsOrderInfo = new GoodsOrderInfo();
		goodsOrderInfo.setStatus(status);
		goodsOrderInfo.setStatusRemark(msg);
		goodsOrderInfo.setSupOrderId(wogreatOrderId);
		goodsOrderInfo.setRegisterAccount(merchantId);

		if (supplyName != null && !("".equals(supplyName))) {
			goodsOrderInfo.setSupplyName(supplyName);
		}
		if (goodsCostPrice != null && !("".equals(goodsCostPrice))) {
			int value = Integer.parseInt(goodsCostPrice);
			goodsOrderInfo.setGoodsCostPrice(value);
		}
		if (suppliersId != null && !("".equals(suppliersId))) {
			goodsOrderInfo.setSupplyId(suppliersId);
		}

		try {
			// 根据交易返回的结果更新订单表
			updateGoodsOrder(orderId, head, goodsOrderInfo, goodsOrderDAO);
		} catch (Exception e) {
			log.error("请求ID：" + head.getRequestId() + "根据沃谷返回的结果更新订单异常！", e);
		}
		return resInfo;

	}

	/**
	 * 更新订单
	 * 
	 * @param orderId
	 * @param head
	 * @param info
	 * @param goodsOrderDAO
	 */
	private static void updateGoodsOrder(String orderId, Head head,
			GoodsOrderInfo info, GoodsOrderDAO goodsOrderDAO) {
		info.setOrderId(orderId);
		info.setSynOrAsy("0"); // 同步通知标识
		// 数据更新
		try {
			goodsOrderDAO.update(info);
		} catch (Exception e) {
			log.error(
					"updateGoodsOrder处理[" + head.getRequestId() + "]的请求出现异常！",
					e);
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}
	}

	private static WogreatRespInfo sendHttpRequestOfDirectTrade(String url,
			Map<String, String> map, Head head) {
		WogreatRespInfo resInfo = null;
		HttpClient httpClient = new HttpClient();
		try {
			log.info("请求ID：" + head.getRequestId() + "，发送到沃谷的直充请求参数为：" + url
					+ map);
			String xmlStr = httpClient.doPost(url, map);
			log.info("请求ID：" + head.getRequestId() + "，沃谷直充返回的结果参数为：" + xmlStr);
			// 对返回的xml格式字符串数据进行解析
			if (StringUtils.isNotEmpty(xmlStr)) {
				resInfo = ParseWogreatRespInfo.getInfoOfRecharge(xmlStr);
			}
		} catch (Exception e) {
			log.error("请求ID：" + head.getRequestId() + "沃谷直充交易请求异常！", e);
		}
		return resInfo;
	}

	/**
	 * 拼接请求参数
	 * 
	 * @param info
	 * @param originalGoodsId
	 * @param orderId
	 * @param accDAO
	 * @param rechargeDAO
	 * @param asDAO
	 * @param mechantIP
	 * @return
	 */
	private static Map<String, String> assembleParameterOfTrade(
			SLSHttpInterfaceInfo info, String originalGoodsId, String orderId,
			WogreatAccountDAO accDAO, WogreatRechargeDAO rechargeDAO,
			WogreatAsDAO asDAO, String mechantIP) {
		Map<String, String> map = new HashMap<String, String>();
		String md5key = PropertiesUtil.getValue("wogreat.md5.key", filename);
		// 工号
		String merchantId = PropertiesUtil.getValue("wogreat.merchant.id",
				filename);
		String returnUrl = PropertiesUtil.getValue("wogreat.return.address",
				filename);
		String gameArea = info.getGameArea();
		String gameServer = info.getGameServer();
		String accountTypeName = info.getAccountTypeName();
		String chargeTypeName = info.getChargeTypeName();
		String buyNum = info.getBuyNum();
		String gameAccount = info.getGameAccount();
		WogreatAccountType account = new WogreatAccountType();
		account.setProductId(originalGoodsId);
		account.setAccountTypeName(accountTypeName);
		List<WogreatAccountType> accList = accDAO
				.queryByProIdAndAccountName(account);
		String game = "";
		String gameName = "";
		String targetAccountType = "";
		String targetAccountTypeName = "";
		if (accList != null && !accList.isEmpty()) {
			account = accList.get(0);
			gameName = account.getGameName();
			game = account.getGameNameValue();
			targetAccountType = account.getAccountTypeValue();
			targetAccountTypeName = account.getAccountTypeName();
		}
		WogreatRechargeType recharge = new WogreatRechargeType();
		recharge.setProductId(originalGoodsId);
		recharge.setRechargeTypeName(chargeTypeName);
		List<WogreatRechargeType> rechargeList = rechargeDAO
				.queryByProIdAndRechargeName(recharge);
		String rechargeMode = "";
		String rechargeModeName = "";
		if (rechargeList != null && !rechargeList.isEmpty()) {
			recharge = rechargeList.get(0);
			gameName = recharge.getGameName();
			game = recharge.getGameNameValue();
			rechargeMode = recharge.getRechargeTypeValue();
			rechargeModeName = recharge.getRechargeTypeName();
		}
		WogreatAreaServer as = new WogreatAreaServer();
		as.setProductId(originalGoodsId);
		as.setAreaName(gameArea);
		as.setServerName(gameServer);
		List<WogreatAreaServer> asList = asDAO.queryByProIdAndASName(as);
		String area = "";
		String areaName = "";
		String server = "";
		String serverName = "";
		if (asList != null && !asList.isEmpty()) {
			as = asList.get(0);
			gameName = as.getGameName();
			game = as.getGameNameValue();
			area = as.getAreaValue();
			areaName = as.getAreaName();
			server = as.getServerValue();
			serverName = as.getServerName();
		}
		String data = merchantId + orderId + originalGoodsId + buyNum
				+ gameAccount + md5key;
		String sign = UtilMD5Encryption.createMD5Encryption(data);
		map.put("MerchantID", merchantId);
		map.put("MerchantOrderID", orderId);
		map.put("ProductID", originalGoodsId);
		map.put("BuyAmount", buyNum);
		map.put("TargetAccount", gameAccount);
		if (StringUtils.isNotEmpty(targetAccountType)) {
			map.put("TargetAccountType", targetAccountType);
		}
		if (StringUtils.isNotEmpty(targetAccountTypeName)) {
			map.put("TargetAccountTypeName", targetAccountTypeName);
		}
		if (StringUtils.isNotEmpty(targetAccountType)) {
			map.put("TargetAccountType", targetAccountTypeName);
		}
		if (StringUtils.isNotEmpty(rechargeMode)) {
			map.put("RechargeMode", rechargeMode);
		}
		if (StringUtils.isNotEmpty(rechargeModeName)) {
			map.put("RechargeModeName", rechargeModeName);
		}
		if (StringUtils.isNotEmpty(game)) {
			map.put("Game", game);
		}
		if (StringUtils.isNotEmpty(gameName)) {
			map.put("GameName", gameName);
		}
		if (StringUtils.isNotEmpty(area)) {
			map.put("Area", area);
		}
		if (StringUtils.isNotEmpty(areaName)) {
			map.put("AreaName", areaName);
		}
		if (StringUtils.isNotEmpty(server)) {
			map.put("Server", server);
		}
		if (StringUtils.isNotEmpty(areaName)) {
			map.put("AreaName", areaName);
		}
		if (StringUtils.isNotEmpty(serverName)) {
			map.put("ServerName", serverName);
		}
		map.put("CustomerIP", mechantIP);
		map.put("ResponseUrl", returnUrl);
		map.put("Sign", sign);

		return map;
	}

	/**
	 * 更新本地订单记录
	 * 
	 * @param supplyName
	 * @param goodsCostPrice
	 * @param suppliersId
	 * @param goodsOrderDAO
	 * @param head
	 */
	public static void updateOrderInfo(String orderId, String supplyName,
			String goodsCostPrice, String suppliersId,
			GoodsOrderDAO goodsOrderDAO, Head head, String merchantId) {
		GoodsOrderInfo goodsOrderInfo = new GoodsOrderInfo();
		goodsOrderInfo.setOrderId(orderId);
		goodsOrderInfo.setSupplyName(supplyName);

		int value = Integer.parseInt(goodsCostPrice);
		goodsOrderInfo.setGoodsCostPrice(value);
		goodsOrderInfo.setSupplyId(suppliersId);
		goodsOrderInfo.setRegisterAccount(merchantId);
		// 数据更新
		try {
			goodsOrderDAO.update(goodsOrderInfo);
		} catch (Exception e) {
			log.error("处理[" + head.getRequestId() + "]的请求出现异常！", e);
		}
	}

}
